package cn.gov.mwr.szy206;

import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
 




import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.gov.mwr.szy206.body.BodyDown;
import cn.gov.mwr.szy206.utils.ByteUtil;
 

public class SzyCaller {

	private Logger logger = LoggerFactory.getLogger(SzyCaller.class);

	private static String SEP = ",";

	private static int DIR = 0;// 表示此帧报文是由中心站发出的下行报文；
	private static int DIV = 0;// 表示此帧报文为单帧。
	private static int FCB = 3;// 表示帧计数位,二进制11表示为3

	public SzyCaller() {

	}

	/**
	 * 查询命令：适用于
	 * 
	 ** 0x50:// 查询遥测终端、中继站地址
	 * 
	 * 0x51:// 查询遥测终端、中继站时钟
	 * 
	 * 0x52:// 查询遥测终端工作模式
	 * 
	 * 0x53:// 查询遥测终端的数据自报种类及时间间隔
	 * 
	 * 0x54:// 查询遥测终端需查询的实时数据种类
	 * 
	 * 0x55:// 查询遥测终端最近成功充值量和现有剩余水量
	 * 
	 * 0x56:// 查询遥测终端剩余水量和报警值
	 * 
	 * 0x57:// 查询遥测终端水位基值、水位上下限
	 * 
	 * 0x58:// 查询遥测终端水压上、下限
	 * 
	 * 0x59:// 查询遥测终端水质参数种类、上限值
	 * 
	 * 0x5A:// 查询遥测终端水质参数种类、下限值
	 * 
	 * 0x5D:// 查询遥测终端的事件记录
	 * 
	 * 0x5E:// 查询遥测终端状态和报警状态
	 * 
	 * 0x5F:// 查询水泵电机实时工作数据
	 * 
	 * 0x60:// 查询遥测终端转发中继引导码长
	 * 
	 * 0x61:// 查询遥测终端图像记录
	 * 
	 * 0x62:// 查询中继站转发终端地址
	 * 
	 * 0x63:// 查询中继站工作机状态和切换记录
	 * 
	 * 0x64:// 查询遥测终端流量参数上限值
	 * 
	 * 0xB0:// 查询遥测终端实时值（AFN=B0H)
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmdQuery(String stcd, String afn) {

		return cmdAfn(stcd, ByteUtil.HexStringToBinary(afn)[0]);
		// //---------------------
		// String funcCode = afn;
		//
		// // 1、封装数据
		// DataDown userdata = new DataDown();
		// userdata.setAFN(ByteUtil.HexStringToBinary(afn)[0]);
		//
		// SzyMessageBody msgBody = new SzyMessageBody();
		// msgBody.setControl(SzyBuilder.newControl(DIR, DIV, FCB, 14));
		// msgBody.setAddress(SzyBuilder.newStcd(stcd));
		// msgBody.setUserData(userdata);
		//
		// // 2、封装消息
		// SzyMessage message = SzyBuilder.newMessage(msgBody);

		// // 获取消息体，并计算CRC
		// byte[] crc = CrcUtil.crc8Check(msgBody.getContent());
		//
		// SzyHeader header = new SzyHeader();
		// header.setBodyLength(msgBody.getLength());// 此处若大于255，则需要拆分包
		//
		// SzyMessage message = new SzyMessage();
		// message.setHeader(header);
		// message.setBody(msgBody);
		// message.setCRC(crc);
		// message.setEOF(SzySymbol.EOF);

		// Message转义为byte数组
		// String hexString = SzyBuilder.toHexString(message);
		// System.out.println(">> " + hexString);

		// 2、入库留痕
		// this.writeDb(stcd, funcCode, null, hexString);
	}

	/**
	 * 设置命令，需根据不同的命令参数，设置不同的命令
	 * 
	 * AFN=10H 设置遥测终端或中继站地址
	 * 
	 * AFN=11H 设置遥测终端或中继站时钟
	 * 
	 * AFN=12H 设置遥测终端的工作模式
	 * 
	 * AFN=A1H 设置遥测终端的数据自报种类及时间间隔
	 * 
	 * AFN=A0H 设置遥测站需查询的实时数据种类
	 * 
	 * AFN=15H 设置遥测终端的本次充值量
	 * 
	 * AFN=16H 设置遥测终端的剩余水量报警值
	 * 
	 * AFN=17H 设置遥测终端的水位基值、水位上下限
	 * 
	 * AFN=18H 设置遥测终端水压上、下限值
	 * 
	 * AFN=19H 设置遥测终端水质参数种类、上限值
	 * 
	 * AFN=1AH 设置遥测终端下限值水质参数种类、下限值
	 * 
	 * AFN=1BH 设置终端站水量的表底（初始）值
	 * 
	 * AFN=1CH 设置终端站转发中继引导码长值
	 * 
	 * AFN=1DH 设置中继站转发终端地址
	 * 
	 * AFN=1EH 设置中继站工作机自动切换、自报状态
	 * 
	 * AFN=1FH 设置遥测终端的流量参数上限值
	 * 
	 * AFN=20H 设置遥测终端检测参数启报阈值及固态存储时间段间隔（AFN=20H）
	 * 
	 * AFN=30H 设置遥测终端IC 卡功能有效
	 * 
	 * AFN=32H 定值控制功能投入
	 * 
	 * AFN=33H 定值控制功能退出
	 * 
	 * AFN=34H 定值量设定
	 * 
	 * 
	 * @param stcd
	 * @param afn
	 */

	/**
	 * AFN=10H 设置遥测终端或中继站地址
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd10(String stcd, String newStcd) {

		byte[] data = SzyBuilder.newStcd(newStcd);
		return cmdAfnData(stcd, (byte) 0x10, data);
	}

	/**
	 * 
	 * AFN=11H 设置遥测终端或中继站时钟
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd11(String stcd) {

		byte afn = (byte) 0x11;
		byte[] data = SzyBuilder.newClock();
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=12H 设置遥测终端的工作模式
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd12(String stcd, String mode) {

		byte afn = (byte) 0x12;
		byte[] data = ByteUtil.HexStringToBinary(StringUtils.leftPad(mode, 2,
				"0"));
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=A1H 设置遥测终端的数据自报种类及时间间隔
	 * 
	 * @param stcd
	 * @param type
	 * @param data
	 */
	public SzyMessage cmdA1(String stcd, String type, int[] data) {
		return null;
	}

	/**
	 * AFN=A0H 设置遥测站需查询的实时数据种类
	 * 
	 * @param stcd
	 * @param type
	 */
	public SzyMessage cmdA0(String stcd, String type) {
		return null;
	}

	/**
	 * AFN=15H 设置遥测终端的本次充值量
	 * 
	 * @param stcd
	 * @param val
	 */
	public SzyMessage cmd15(String stcd, int val) {
		byte afn = (byte) 0x15;

		String str = Integer.toString(val);
		str = StringUtils.leftPad(str, 8, "0");
		byte[] data = ByteUtil.str2Bcd(str);
		ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=16H 设置遥测终端的剩余水量报警值
	 * 
	 * @param stcd
	 * @param val
	 */
	public SzyMessage cmd16(String stcd, int val) {
		byte afn = (byte) 0x16;

		String str = Integer.toString(val);
		str = StringUtils.leftPad(str, 6, "0");
		byte[] data = ByteUtil.str2Bcd(str);
		ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=17H 设置遥测终端的水位基值、水位上下限
	 * 
	 * @param stcd
	 * @param base
	 * @param lowLimit
	 * @param topLimit
	 */
	public SzyMessage cmd17(String stcd, double base, double lowLimit, double topLimit) {

		return 	cmd17(stcd, new double[] { base }, new double[] { lowLimit },
				new double[] { topLimit });
	}

	public SzyMessage cmd17(String stcd, double[] base, double[] lowLimit,
			double[] topLimit) {
		byte afn = (byte) 0x17;

		// String str = Integer.toString(val);
		// str = StringUtils.leftPad(str, 6, "0");
		// byte[] data = ByteUtil.str2Bcd(str);

		byte[] data = new byte[base.length * 7];
		int pos = 0;
		for (int i = 0; i < base.length; i++) {

			String b_pattern = "0000.00";
			byte[] b = convertData(base[i], b_pattern, 6);

			String pattern = "00.00";
			byte[] low = convertData(lowLimit[i], pattern, 4);
			byte[] top = convertData(topLimit[i], pattern, 4);

			if (base[i] < 0) {
				b[3] = (byte) ((byte) (b[3] & 0x7F) | (byte) (0x01 << 7));
			}

			System.arraycopy(b, 0, data, pos, b.length);
			pos = pos + b.length;
			System.arraycopy(low, 0, data, 3, low.length);
			pos = pos + low.length;
			System.arraycopy(top, 0, data, 5, top.length);
			pos = pos + top.length;

		}

		// ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);

	}

	private byte[] convertData(double d, String pattern, int length) {

		if (d < 0)
			d = d * -1;

		DecimalFormat df = new DecimalFormat(pattern);
		System.out.println("Integer  is displayed as " + df.format(d));

		String str = "" + df.format(d);
		str = StringUtils.replace(str, ".", "");
		str = StringUtils.leftPad(str, length, "0");
		byte[] data = ByteUtil.str2Bcd(str);

		ArrayUtils.reverse(data);

		return data;
	}

	public SzyMessage cmd18(String stcd, double topLimit, double lowLimit) {

		return cmd18(stcd, new double[] { topLimit }, new double[] { lowLimit });
	}

	/**
	 * AFN=18H 设置遥测终端水压上、下限值
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd18(String stcd, double[] topLimit, double[] lowLimit) {
		byte afn = (byte) 0x18;

		byte[] data = new byte[topLimit.length * 8];

		String pattern = "000000.00";
		int pos = 0;
		for (int i = 0; i < topLimit.length; i++) {
			byte[] top = convertData(topLimit[i], pattern, 4);
			byte[] low = convertData(lowLimit[i], pattern, 4);

			System.arraycopy(top, 0, data, pos, top.length);
			pos = pos + top.length;
			System.arraycopy(low, 0, data, pos, low.length);
			pos = pos + low.length;
		}

		// ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);
	}

	public SzyMessage cmdSZ(String stcd, byte afn, String binstr, double[] data) {

		byte[] type = convertSZ(binstr);

		// 计算字节数
		int blen = 5;
		int bpos = 0;
		ArrayList<byte[]> list = new ArrayList<byte[]>();
		String tmpstr = binstr;
		for (int i = 0, len = tmpstr.length(); i < len; i++) {
			String bstr = tmpstr.substring(i, i + 1);
			if (bstr.equals("1")) {
				DataType dt = SzyConst.SZ.get("" + i);

				StringBuffer sb = new StringBuffer();
				sb.append(StringUtils.leftPad("", dt.getLength(), "0"));
				sb.append(".");
				sb.append(StringUtils.leftPad("", dt.getDecimal(), "0"));
				String pattern = sb.toString();

				// System.out.println(">> i " + i + dt.getText() + " bpos " +
				// bpos
				// + "  Length() " + dt.getLength()
				// + "  Decimal() " + dt.getDecimal() + " pattern " + pattern);

				byte[] temp = convertData(data[bpos], pattern, dt.getBlen() * 2);
				bpos++;

				list.add(temp);

				if (i == 24) {
					blen = blen + 5;
				} else {
					blen = blen + 4;
				}

			}
		}

		// ------------------------------------------
		// byte afn = (byte) 0x19;
		byte[] result = new byte[blen];

		System.arraycopy(type, 0, result, 0, type.length);
		int rpos = 5;
		for (int i = 0; i < list.size(); i++) {
			// 水质的每一个种类都不一样
			byte[] temp = list.get(i);

			System.arraycopy(temp, 0, result, rpos, temp.length);
			rpos = rpos + temp.length;

		}

		return cmdAfnData(stcd, afn, result);

	}

	// 先拆分，后反转
	private byte[] convertSZ(String binstr) {

		int len = binstr.length() / 8;
		byte[] result = new byte[len];
		for (int i = 0; i < len; i++) {
			String substr = binstr.substring(i * 8, (i + 1) * 8);
			substr = StringUtils.reverse(substr);
			Integer temp = Integer.valueOf(substr, 2); //
			result[i] = ByteUtil.ubyteToBytes(temp)[0];

		}
		return result;
	}

	/**
	 * AFN=19H 设置遥测终端水质参数种类、上限值
	 * 
	 * @param stcd
	 * @param binstr
	 */
	public SzyMessage cmd19(String stcd, String binstr, double[] data) {
		return cmdSZ(stcd, (byte) 0x19, binstr, data);
	}

	/**
	 * AFN=1AH 设置遥测终端下限值水质参数种类、下限值
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd1A(String stcd, String binstr, double[] data) {
		return cmdSZ(stcd, (byte) 0x1A, binstr, data);
	}

	/**
	 * AFN=1BH 设置终端站水量的表底（初始）值
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd1B(String stcd, double[] base) {
		byte afn = (byte) 0x1B;

		byte[] data = new byte[base.length * 5];

		String pattern = "0000000000";
		int pos = 0;
		for (int i = 0; i < base.length; i++) {
			byte[] top = convertData(base[i], pattern, 5 * 2);

			System.arraycopy(top, 0, data, pos, top.length);
			pos = pos + top.length;
		}

		// ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);
	}

	/**
	 * AFN=1CH 设置终端站转发中继引导码长值
	 * 
	 * @param stcd
	 * @param len
	 *            取值范围为0～255，单位为s。
	 */
	public SzyMessage cmd1C(String stcd, int len) {

		byte afn = (byte) 0x1C;
		byte[] data = ByteUtil.ubyteToBytes(len);
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=1DH 设置中继站转发终端地址
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd1D(String stcd, String[] address) {

		byte[] data;
		if (address != null) {
			data = new byte[address.length * 5];
			int pos = 0;
			for (String fstcd : address) {
				byte[] fstcdBytes = SzyBuilder.newStcd(fstcd);
				System.arraycopy(fstcdBytes, 0, data, pos, 5);
				pos = pos + 5;
			}

		} else {
			data = null;
		}

		byte afn = (byte) 0x1D;
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=1EH 设置中继站工作机自动切换、自报状态
	 * 
	 * @param stcd
	 * @param binstr
	 */
	public SzyMessage cmd1E(String stcd, String binstr) {

		byte afn = (byte) 0x1E;
		Integer status = Integer.valueOf(binstr, 2); //
		byte[] data = ByteUtil.ubyteToBytes(status);
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=1FH 设置遥测终端的流量参数上限值
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd1F(String stcd, double[] topLimit) {

		byte afn = (byte) 0x1F;

		byte[] data = new byte[topLimit.length * 5];

		String pattern = "0000000.000";
		int pos = 0;
		for (int i = 0; i < topLimit.length; i++) {
			double topval = topLimit[i];
			byte[] top = new byte[5];
			if (topval < 0) {
				topval = topval * -1;
				top = convertData(topval, pattern, 5 * 2);
				top[4] = (byte) (top[4] | 0xF0);
			} else {
				top = convertData(topval, pattern, 5 * 2);
				top[4] = (byte) (top[4] & 0x0F);
			}

			System.arraycopy(top, 0, data, pos, top.length);
			pos = pos + top.length;
		}

		// ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=20H 设置遥测终端检测参数启报阈值及固态存储时间段间隔（AFN=20H）
	 * 
	 * @param stcd
	 * @param type
	 * @param interval
	 * @param val
	 */
	public SzyMessage cmd20(String stcd, int atype, int interval, int btype,
			double val) {

		byte afn = (byte) 0x20;

		byte[] a = ByteUtil.ubyteToBytes(atype);
		byte[] b = ByteUtil.ubyteToBytes(btype);

		byte type = (byte) ((byte) (a[0] << 4) | b[0]);

		byte[] c = ByteUtil.ubyteToBytes(interval);
		DataType dt = null;
		switch (btype) {
		case 1:
			dt = new DataType(1, "雨量参数", 3, 5, 1);
			break;
		case 2:
			dt = new DataType(2, "水位参数", 4, 4, 3);
			break;
		case 3:
			dt = new DataType(3, "流量（水量）参数", 5, 6, 3);
			break;
		case 4:
			dt = new DataType(4, "流速参数", 3, 2, 3);
			break;
		case 5:
			dt = new DataType(5, "闸位参数", 3, 3, 2);
			break;
		case 6:
			dt = new DataType(6, "功率参数", 3, 6, 0);
			break;
		case 7:
			dt = new DataType(7, "气压参数", 3, 5, 0);
			break;
		case 8:
			dt = new DataType(8, "风速参数", 3, 3, 2);
			break;
		case 9:
			dt = new DataType(9, "水温参数", 2, 2, 1);
			break;
		case 10:
			// new DataType(10, "水质参数", 4));
			break;
		case 11:
			dt = new DataType(11, "土壤含水率参数", 2, 3, 1);
			break;
		case 12:
			dt = new DataType(12, "蒸发量参数", 3, 4, 1);
			break;
		case 13:
			dt = new DataType(13, "水压参数", 4, 6, 2);
			break;
		default:
			dt = new DataType(16, "defautl", 0, 0, 0);
		}

		StringBuffer sb = new StringBuffer();
		sb.append(StringUtils.leftPad("", dt.getLength(), "0"));
		sb.append(".");
		sb.append(StringUtils.leftPad("", dt.getDecimal(), "0"));

		String pattern = sb.toString();
		byte[] temp = convertData(val, pattern, dt.getBlen() * 2);

		byte[] data = new byte[2 + temp.length];
		System.arraycopy(new byte[] { type }, 0, data, 0, 1);
		System.arraycopy(c, 0, data, 1, 1);
		System.arraycopy(temp, 0, data, 2, temp.length);
		// ArrayUtils.reverse(data);
		return cmdAfnData(stcd, afn, data);

	}

	/**
	 * AFN=30H 设置遥测终端IC 卡功能有效
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd30(String stcd) {
		return cmdAfnData(stcd, (byte) 0x30, null);
	}

	/**
	 * AFN=30H 取消遥测终端IC 卡功能
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd31(String stcd) {
		return cmdAfnData(stcd, (byte) 0x31, null);
	}

	/**
	 * AFN=32H 定值控制功能投入
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd32(String stcd) {
		return cmdAfnData(stcd, (byte) 0x32, null);
	}

	/**
	 * AFN=33H 定值控制功能退出
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd33(String stcd) {
		return cmdAfnData(stcd, (byte) 0x33, null);
	}

	/**
	 * AFN=34H 定值量设定
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmd34(String stcd, double val) {
		byte afn = (byte) 0x17;

//		byte[] data = convertData(data[bpos], pattern, 5 * 2);
//
//		return cmdAfnData(stcd, afn, data);
		return null;
	}

	/**
	 * 内部函数，针对不需要设定“内部数据”的设置命令
	 * 
	 * @param stcd
	 * @param afn
	 * @return
	 */
	private SzyMessage cmdAfnData(String stcd, byte afn, byte[] data) {
		BodyDown userdata = new BodyDown();
		userdata.setAFN(afn);
		userdata.setData(data);
		userdata.setPw(SzyBuilder.newPW(8, 50));
		userdata.setTp(SzyBuilder.newTP(0));

		SzyMessageBody msgBody = new SzyMessageBody();
		msgBody.setControl(SzyBuilder.newControl(DIR, DIV, FCB, 0));
		msgBody.setAddress(SzyBuilder.newStcd(stcd));
		msgBody.setUserData(userdata);

		// 2、封装消息
		SzyMessage message = SzyBuilder.newMessage(msgBody);

		String hexString = SzyBuilder.toHexString(message);
		System.out.println(">> " + hexString);

		return message;
	}

	/**
	 * 内部函数，针对不需要设定“内部数据”的设置命令
	 * 
	 * @param stcd
	 * @param afn
	 * @return
	 */
	private SzyMessage cmdAfn(String stcd, byte afn) {
		BodyDown userdata = new BodyDown();
		userdata.setAFN(afn);
		userdata.setData(null);

		// userdata.setTp(SzyBuilder.newTP(0));
		// userdata.setPw(SzyBuilder.newPW(method, secret));

		SzyMessageBody msgBody = new SzyMessageBody();
		msgBody.setControl(SzyBuilder.newControl(DIR, DIV, FCB, 0));
		msgBody.setAddress(SzyBuilder.newStcd(stcd));
		msgBody.setUserData(userdata);

		// 2、封装消息
		SzyMessage message = SzyBuilder.newMessage(msgBody);

		String hexString = SzyBuilder.toHexString(message);
		System.out.println(">> " + hexString);

		return message;
	}

	/**
	 * 查询终端固态存储数据（AFN=B1H）
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmdB1(String stcd, int type, String startTime, String endTime) {

		byte[] high = ByteUtil.ubyteToBytes(type - 1);
		byte d1 = (byte) ((high[0] << 4) & ByteUtil.ubyteToBytes(type)[0]);
		byte[] d2 = ByteUtil.str2Bcd(startTime + endTime);

		byte[] data = new byte[9];
		System.arraycopy(new byte[] { d1 }, 0, data, 0, 1);
		System.arraycopy(d2, 0, data, 1, 8);

		byte afn = (byte) 0xB1;
		return  cmdAfnData(stcd, afn, data);
	}

	/**
	 * 查询终端内存自报数据（AFN=B2H）
	 * 
	 * @param stcd
	 * @param afn
	 */
	public SzyMessage cmdB2(String stcd, String type, String startTime, String endTime) {

		int n = Integer.parseInt(type, 2);
		byte[] f = ByteUtil.ubyteToBytes(n);
		byte d1 = (byte) ((f[0] << 4) & ByteUtil.ubyteToBytes(n + 1)[0]);
		byte[] d2 = ByteUtil.str2Bcd(startTime + endTime);

		byte[] data = new byte[9];
		System.arraycopy(new byte[] { d1 }, 0, data, 0, 1);
		System.arraycopy(d2, 0, data, 1, 8);

		byte afn = (byte) 0xB2;
		return cmdAfnData(stcd, afn, data);
	}

	/**
	 * 查询遥测终端图像记录（AFN=61H）
	 * 
	 * @param stcd
	 * @param seq
	 */
	public SzyMessage cmd61(String stcd, int seq) {

		byte afn = (byte) 0x61;
		byte[] data = ByteUtil.ubyteToBytes(seq);
		return cmdAfnData(stcd, afn, data);

	}

	// ----------------------------------------------
	//
	//
	// ------------- 控制命令 -------------
	//
	//
	// ----------------------------------------------

	/**
	 * 复位遥测终端参数和状态命令（AFN=90H）
	 * 
	 * @param stcd
	 * @param hex
	 */
	public SzyMessage cmd90(String stcd, String hex) {
		byte afn = (byte) 0x90;
		byte[] data = ByteUtil.HexStringToBinary(hex);
		return cmdAfnData(stcd, afn, data);
	}

	/**
	 * 清空遥测终端的历史数据单元（AFN=91H）
	 * 
	 * @param stcd
	 * @param hex
	 */
	public SzyMessage cmd91(String stcd, String hex) {
		byte afn = (byte) 0x90;

		// int num = Integer.parseInt(binstr, 2);
		// byte[] data = ByteUtil.ubyteToBytes(num);
		byte[] data = ByteUtil.HexStringToBinary(hex);
		return cmdAfnData(stcd, afn, data);
	}

	/**
	 * 遥控启动水泵或阀门/闸门（AFN=92H）
	 * 
	 * @param stcd
	 * @param seq
	 */
	public SzyMessage cmd92(String stcd, int type, int num) {

		byte afn = (byte) 0x92;
		byte data = (byte) ((ByteUtil.ubyteToBytes(num)[0] << 4) | ByteUtil
				.ubyteToBytes(type)[0]);
		return cmdAfnData(stcd, afn, new byte[] { data });

	}

	/**
	 * 遥控关闭水泵或阀门/闸门（AFN=93H）
	 * 
	 * @param stcd
	 * @param type
	 * @param num
	 */
	public SzyMessage cmd93(String stcd, int type, int num) {
		byte afn = (byte) 0x93;
		byte data = (byte) ((ByteUtil.ubyteToBytes(num)[0] << 4) | ByteUtil
				.ubyteToBytes(type)[0]);
		return cmdAfnData(stcd, afn, new byte[] { data });
	}

	/**
	 * 遥控关闭水泵或阀门/闸门（AFN=93H）
	 * 
	 * @param stcd
	 * @param type
	 * @param num
	 */
	public SzyMessage cmd94(String stcd) {
		byte afn = (byte) 0x94;
		return cmdAfnData(stcd, afn, null);
	}

	/**
	 * 遥控中继站工作机切换（AFN=95H）
	 * 
	 * @param stcd
	 * @param type
	 * @param num
	 */
	public SzyMessage cmd95(String stcd) {
		byte afn = (byte) 0x95;
		return cmdAfnData(stcd, afn, null);
	}

	/**
	 * 修改遥测终端密码（AFN=96H）
	 * 
	 * @param stcd
	 * @param pwd
	 */
	public SzyMessage cmd96(String stcd, String pwd) {
		byte afn = (byte) 0x96;
		byte[] data = ByteUtil.str2Bcd(pwd);
		return cmdAfnData(stcd, afn, data);
	}

	// private void cmdNormal(String stcd, byte funcCode) throws Exception {
	//
	// Station station = null;
	//
	// station = HydroServer.getInstance().getStationManager()
	// .getStation(stcd);
	//
	// if (station != null) {
	//
	// DownCommand cmd = new DownCommand();
	// cmd.setCenterAddr(ByteUtil.HexStringToBinary(HydroConfig
	// .getCenterAddr()));
	// cmd.setStationAddr(ByteUtil.HexStringToBinary(station.getF02()));
	// cmd.setPassword(ByteUtil.HexStringToBinary(station.getF03()));
	// cmd.setBodyStartBit(Symbol.STX);
	// cmd.setEof(Symbol.ENQ);
	// cmd.setFuncCode(fu)ncCode);
	// IMessage message = cmd.send37Message(1, null);
	//
	// // 保存进数据库
	// this.writeDb(stcd, ByteUtil.toHexString(funcCode), null, cmd
	// .printHexString(message));
	// }
	// }

	/**
	 * 测试查询方法
	 */
	public void testQuery() {
		SzyCaller caller = new SzyCaller();
		String stcd = "42010111067";
		// 查询命令
		caller.cmdQuery(stcd, "50");// 查询遥测终端、中继站地址
		caller.cmdQuery(stcd, "51");// 查询遥测终端、中继站时钟
		caller.cmdQuery(stcd, "52");// 查询遥测终端工作模式
		caller.cmdQuery(stcd, "53");// 查询遥测终端的数据自报种类及时间间隔
		caller.cmdQuery(stcd, "54");// 查询遥测终端需查询的实时数据种类
		caller.cmdQuery(stcd, "55");// 查询遥测终端最近成功充值量和现有剩余水量
		caller.cmdQuery(stcd, "56");// 查询遥测终端剩余水量和报警值
		caller.cmdQuery(stcd, "57");// 查询遥测终端水位基值、水位上下限
		caller.cmdQuery(stcd, "58");// 查询遥测终端水压上、下限
		caller.cmdQuery(stcd, "59");// 查询遥测终端水质参数种类、上限值
		caller.cmdQuery(stcd, "5A");// 查询遥测终端水质参数种类、下限值
		caller.cmdQuery(stcd, "5D");// 查询遥测终端的事件记录
		caller.cmdQuery(stcd, "5E");// 查询遥测终端状态和报警状态
		caller.cmdQuery(stcd, "5F");// 查询水泵电机实时工作数据
		caller.cmdQuery(stcd, "60");// 查询遥测终端转发中继引导码长
		caller.cmdQuery(stcd, "61");// 查询遥测终端图像记录
		caller.cmdQuery(stcd, "62");// 查询中继站转发终端地址
		caller.cmdQuery(stcd, "63");// 查询中继站工作机状态和切换记录
		caller.cmdQuery(stcd, "64");// 查询遥测终端流量参数上限值
		caller.cmdQuery(stcd, "B0");// 查询遥测终端实时值（AFN=B0H)
	}

	/**
	 * 测试方法
	 * 
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		// 设置命令
		int code = Integer.parseInt("0011", 2);
		System.out.println("code " + code);

		String stcd = "320104000002";
		SzyCaller caller = new SzyCaller();
		// caller.cmd10("805001000002", "320101000001");//pass

		// caller.cmd11(stcd);//pass

		// caller.cmd12(stcd, "10");//pass

		// caller.cmd15(stcd, 100);//pass

		// caller.cmd16(stcd, 200);//pass

		// caller.cmd17(stcd, 0, 2.00, 10.00);// （此功能已经OK）

		// String d = "12.34";
		// System.out.println("code " + StringUtils.replace(d, ".", ""));
		// caller.cmd18(stcd, 33.00, 2.00);// （此功能已经OK）

		// String binstr = "1110101000000000000000000000000000000000";
		// double[] data = new double[] { 22.0, 11.00, 9.0, 8, 7 };
		// caller.cmd1A(stcd, binstr, data);

		// caller.cmd1B(stcd, new double[] { 2222, 3333 });

		// caller.cmd1F(stcd, new double[] { 22222 });

//		caller.cmd20(stcd, 0, 5, 1, 3.0);
//
//		caller.cmd30(stcd);
		
//		caller.cmd33(stcd);
		
		caller.cmd34(stcd,1234);
	}

}
